<?php

/*
 * IXWEncrypt
 * use IXWEncrypt algorithm 
 * @author Wolfhead <meixueting@snda.com>
 */

class IXWEncrypt
{
    public static function Encrypt($srcstr)
    {
        $srcBytes = array_values(unpack("C*", $srcstr));
        $dstBytes = array();
        
        
        $keyIndex = $srcBytes[0];
        for ($i = 0; $i < count($srcBytes); $i++)
        {
            $dstBytes[$i] = 0x00 | (($srcBytes[$i] ^ self::$keyBytes[$keyIndex]));
            $keyIndex = (($keyIndex + 1) % count(self::$keyBytes));
        }
        
        $dstBytes[] = 0;
        $dstBytes[count($dstBytes) - 1] = $srcBytes[0];
        //var_dump($srcBytes);
        
        for ($i = 0; $i <= count(self::$iMod) - 1; $i++)
        {
            $x = 0x00000000 | (self::$iMod[$i][0] % count($dstBytes));
            $y = 0x00000000 | (self::$iMod[$i][1] % count($dstBytes));

            $t = 0x00 | $dstBytes[$x];

            $dstBytes[$x] = $dstBytes[$y];
            $dstBytes[$y] = $t;
        }
        //var_dump($dstBytes);
        $sb = "";
        
        for ($i = 0; $i < count($dstBytes); $i++)
        {
            $sb .= str_pad(base_convert($dstBytes[$i], 10, 16), 2, "0", STR_PAD_LEFT);
        }
        $sb = strtoupper($sb);
        
        
        $value = $sb;
        for ($i = 0; $i < count(self::$iChar); $i++)
        {
            $value = str_replace(self::$iChar[$i][0], self::$iChar[$i][1],$value);
        }
        
        
        return $value;
    }
    
    public static function Decrypt($srcstr)
    {
        for ($i = count(self::$iChar) - 1 ; $i >= 0; $i--)
        {
            $srcstr = str_replace(self::$iChar[$i][1], self::$iChar[$i][0] ,$srcstr);
        }

        $srcBytes = array();
        for ($i = 0; $i < strlen($srcstr); $i += 2)
        {
            $j = $i / 2;
            $sub = substr($srcstr, $i, 2);
            $srcBytes[$j] = base_convert($sub, 16, 10);
        }
        
        
        for ($i = count(self::$iMod) - 1; $i >= 0; $i--)
        {
            $x = self::$iMod[$i][0] % count($srcBytes);
            $y = self::$iMod[$i][1] % count($srcBytes);

            $t = $srcBytes[$x];
            $srcBytes[$x] = $srcBytes[$y];
            $srcBytes[$y] = $t;
        }
        
        $KeyIndex = $srcBytes[count($srcBytes) - 1];
        
        $dstBytes = array();
        for ($i = 0; $i < count($srcBytes) - 1; $i++)
        {
            $dstBytes[$i] = 0x00 | ($srcBytes[$i] ^ self::$keyBytes[$KeyIndex]);
            $KeyIndex = ($KeyIndex + 1) % count(self::$keyBytes);
        }
        
        $result = "";
        foreach ($dstBytes as $byte)
        {
            $result .= pack("C",$byte);
        }
        
        return $result; 
    }
    
    
    
    protected static $iMod = array(
        array(0,29),array(2,17),array(23,7),array(43,31)
    );
    
    protected static $iChar = array(
        array('9', 'R'), array('5', 'K'), array('F', '9') 
    );
    
    protected static $keyBytes = array(
99,173,136, 78,117, 22,106, 72,167, 32,108,226,249,203,142, 27,
 91, 68, 64,166,237, 47,162, 32,159,184, 36, 57,113,226,198,244,
 83,221,248,253,101, 71,218,247,151, 81,220,146,233,251,254,203,
 75,116,176, 85,221, 95, 18,208,143,232,148,233, 97, 18, 54,164,
 67, 12,104,173, 85,118, 74,168,135,128, 76, 66,217, 42,110,123,
 59,164, 32,  6,205,143,130,127,127, 24,  4,154, 81, 66,166, 83,
 51, 60,216, 93, 69,167,186, 88,119,176,188,241,201, 90,222, 44,
 43,212,144,182,189,190,242, 47,111, 73,116, 73, 65,115, 22,  4,
 35,108, 72, 13, 53,214, 42,  7,103,224, 44,162,185,139, 78,220,
 27,  5,  0,101,173,239, 98,224, 95,121,228,250, 49,162,134,180,
 19,156,184,190, 37,  6,154,184, 87, 17,156, 82,169,187,190,140,
 11, 52,112, 21,157, 31,210,144, 79,169, 84,169, 33,211,246,100,
  3,205, 40,110, 21, 55, 10,104, 71, 65, 12,  2,153,234, 46, 60,
251,101,224,198,141, 78, 66, 63, 63,216,196, 89, 17,  3,102, 19,
243,253,152, 29,  5,103,122, 23, 55,112,124,177,137, 27,158,235,
235,148, 80,118,125,127,178,240, 47,  9, 52, 10,  1, 50,214,195,
227, 44,  8,205,245,151,234,199, 39,161,236, 97,121, 75, 14,156,
219,197,192, 38,109,174, 34,160, 31, 57,164,185,241, 98, 70,115,
211, 93,120,126,229,199, 90,119, 23,208, 92, 17,105,123,126, 76,
203,244, 48,213, 93,223,146, 80, 15,104, 20,106,225,146,182, 35,
195,141,232, 45,213,247,202, 40,  7,  1,204,194, 89,170,238,252,
187, 36,160,134, 77, 15,  2,  0,255,153,132, 26,209,194, 38,211,
179,189, 88,221,197, 39, 58,215,247, 48, 60,114, 73,218, 94,171,
171, 85, 16, 53, 61, 63,114,175,239,201,244,201,193,243,150,132,
163,237,200,142,181, 87,170,136,231, 97,172, 33, 57, 11,206, 91,
155,133,128,229, 45,111,226, 95,223,248,100,121,177, 34,  6, 52,
147, 29, 56, 62,165,134, 26, 56,215,145, 28,209, 41, 59, 62, 11,
139,181,240,150, 29,158, 82, 16,207, 40,212, 41,161, 82,118,227,
131, 76,168,237,149,183,138,231,199,192,140,129, 25,106,174,188,
123,228, 96, 69, 13,206,194,191,191, 89, 68,218,145,131,230,147,
115,125, 24,157,133,230,250,152,183,240,252, 50,  9,154, 30,108,
107, 20,208,246,253,255, 50,111,175,137,180,138,129,179, 86, 67
,
99,173,136, 78,117, 22,106, 72,167, 32,108,226,249,203,142, 27,
 91, 68, 64,166,237, 47,162, 32,159,184, 36, 57,113,226,198,244,
 83,221,248,253,101, 71,218,247,143, 81,220,146,233,251,254,203,
 75,116,176, 85,221, 95, 18,208,151,232,148,233, 97, 18, 54,164,
 67, 12,104,173, 85,118, 74,168,135,128, 76, 66,217, 42,110,123,
 59,164, 32,  6,205,143,130,127,127, 24,  4,154, 81, 66,166, 83,
 51, 60,216, 93, 69,167,186, 88,119,176,188,241,201, 90,222, 44,
 43,212,144,182,189,190,242, 47,111, 73,116, 73, 65,115, 22,  4,
 35,108, 72, 13, 53,239, 42,  7,103,224, 44,162,185,139, 78,220,
 27,  5,  0,101,173,214, 98,224, 95,121,228,250, 49,162,134,180,
 19,156,184,190, 37,  6,184,154, 87, 17,156, 82,169,187,190,140,
 11, 52,112, 21,157, 31,210,144, 79,169, 84,169, 33,211,246,100,
  3,205, 40,110, 21, 55, 10,104, 71, 65, 12,  2,153,234, 46, 60,
251,101,224,198,141, 78, 66, 63, 63,216,196, 89, 17,  3,102, 19,
243,253,152, 29,  5,103,122, 23, 55,112,124,177,137, 27,158,235,
235,148, 80,118,125,127,178,240, 47,  9, 52, 10,  1, 50,214,195,
227, 44,  8,205,245,151,234,199, 39,161,236, 97,121, 75, 14,156,
219,197,192, 38,109,174, 34,160, 31, 57,164,185,241, 98, 70,115,
211, 93,120,126,229,199, 90,119, 23,208, 92, 17,105,123,126, 76,
203,244, 48,213, 93,223,146, 80, 15,104, 20,106,225,146,182, 35,
195,141,232, 45,213,247,202, 40,  7,  1,204,194, 89,170,238,252,
187, 36,160,134, 77, 15,  2,  0,255,153,132, 26,209,194, 38,211,
179,189, 88,221,197, 39, 58,215,247, 48, 60,114, 73,218, 94,171,
171, 85, 16, 53, 61, 63,114,175,239,201,244,201,193,243,150,132,
163,237,200,142,181, 87,170,136,231, 97,172, 33, 57, 11,206, 91,
155,133,128,229, 45,111,226, 95,223,248,100,121,177, 34,  6, 52,
147, 29, 56, 62,165,134, 26, 56,215,145, 28,209, 41, 59, 62, 11,
139,181,240,150, 29,158, 82, 16,207, 40,212, 41,161, 82,118,227,
131, 76,168,237,149,183,138,231,199,192,140,129, 25,106,174,188,
123,228, 96, 69, 13,206,194,191,191, 89, 68,218,145,131,230,147,
115,125, 24,157,133,230,250,152,183,240,252, 50,  9,154, 30,108,
107, 20,208,246,253,255, 50,111,175,137,180,138,129,179, 86, 67
    ); 
}

